#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/sysinfo.h>

#if 0
struct sysinfo {
    long uptime;             /* Seconds since boot */
    unsigned long loads[3];  /* 1, 5, and 15 minute load averages */
    unsigned long totalram;  /* Total usable main memory size */
    unsigned long freeram;   /* Available memory size */
    unsigned long sharedram; /* Amount of shared memory */
    unsigned long bufferram; /* Memory used by buffers */
    unsigned long totalswap; /* Total swap space size */
    unsigned long freeswap;  /* Swap space still available */
    unsigned short procs;    /* Number of current processes */
    unsigned long totalhigh; /* Total high memory size */
    unsigned long freehigh;  /* Available high memory size */
    unsigned int mem_unit;   /* Memory unit size in bytes */
    char _f[20-2*sizeof(long)-sizeof(int)];
    /* Padding to 64 bytes */
};
#endif

int get_sysinfo(void)
{
    struct sysinfo info;
    if (sysinfo(&info) != 0) {
        printf("sysinfo: error!\n");
        return -1;
    }
    printf("uptime: %ld\n", info.uptime);
    printf("load: %lu %lu %lu\n", info.loads[0], info.loads[1], info.loads[2]);
    printf("totalram: %lu\n", info.totalram);
    printf("freeram: %lu\n", info.freeram);
    printf("sharedram: %lu\n", info.sharedram);
    printf("bufferram: %lu\n", info.bufferram);
    printf("totalswap: %lu\n", info.totalswap);
    printf("freeswap: %lu\n", info.freeswap);
    printf("procs: %d\n", info.procs);
    printf("totalhigh: %lu\n", info.totalhigh);
    printf("freehigh: %lu\n", info.freehigh);
    printf("mem_unit: %u\n", info.mem_unit);
}

int get_sysfs(char *key, char *val, int len)
{
    int fd = open(key, O_RDONLY);
    if (fd < 0) {
        printf("open failed: %s\n", key);
        return -1;
    }
    int ret = read(fd, val, len);
    if (ret < 0) {
        printf("read failed: %s\n", key);
        return -1;
    }

    ret = (ret > 0) ? ret - 1 : 0;
    val[ret] = '\0';
    close(fd);
    return ret;
}

int get_thermal(void)
{
    static const char *base = "/sys/class/thermal/thermal_zone";
    static int num = 0;
    char path[64] = {0};
    char type[64] = {0};
    char temp[64] = {0};

    if (num == 0) {
        for (int i= 0; i < 256; i++) {
            sprintf(path, "%s%d", base, i);
            if (access(path, F_OK) == 0) { num = i + 1; } else { break; }
        }
    }

    for (int i= 0; i < num; i++) {
        sprintf(path, "%s%d/%s", base, i, "type");
        get_sysfs(path, type, sizeof(type));
        printf("type: %s, ", type);
        sprintf(path, "%s%d/%s", base, i, "temp");
        get_sysfs(path, temp, sizeof(temp));
        printf("temp: %s\n", temp);
    }
}

int main()
{
    get_sysinfo();
    get_thermal();
    return 0;
}
